home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
apps
/
math
/
classdoc.zoo
/
RFP.a
< prev
next >
Wrap
Text File
|
1991-09-29
|
11KB
|
722 lines
; The Redundance Fighter Packer V1.20
; written by Lutz Vieweg 1991
include src:class.mac
max_mem equ 1024*128*2
min_mem equ 20
main
textr "HPHP48-E"
rpl Type_pgm
rpl Need_1_arg
rpl Dup
rpl $5944 ; CRC nibbles
rpl Drop
include "src:relocpgm.a"
rpl $02dcc
pgmbeg
rpl pgmend-pgmbeg
jsr save_regs
jsr gc
jsr restore_regs
move.ao #stack_ptr,d0
exg.a d1,c
move.a c,d1
move.a c,(d0)
move.a (d1),c
move.a c,d0
add.a #5,d0
move.a (d0),c
move.ao #old_len,d0
move.a c,(d0)
add.a #5,d1
move.a (d1),c
move.ao #old_obj_adr,d0
move.a c,(d0)
jsr restore_regs
bsr work_mem
intoff
bclr #15,st
move.ao #old_len,d0
move.a (d0),a
move.a #1000,c
blt.a a,c,.1z
move.a #$100,d0
move.1 (d0),c
bclr #3,c
move.1 c,(d0)
.1z
bsr compress
bcc .1
bra .2
.1
jsr restore_regs
move.ao #new_len,d0
move.a (d0),c
jsr blkalloc
exg.a d0,c
move.ao #new_obj_adr,d0
move.a c,(d0)
move.a c,d1
move.ao #new_len,d0
move.a (d0),a
move.ao #work_mem_adr,d0
move.a (d0),c
move.a c,d0
move.a a,c
jsr blkcopy
move.ao #stack_ptr,d0
move.a (d0),c
move.a c,d1
add.a #5,d1
move.ao #new_obj_adr,d0
move.a (d0),c
move.a c,(d1)
.2
move.ao #work_mem_adr,d0
move.a (d0),c
move.a c,d1
move.a #$02dcc,c
move.a c,(d1)
add.a #5,d1
move.ao #work_mem_len,d0
move.a (d0),c
sub.a #5,c
move.a c,(d1)
leave_code
move.a #$100,d0
move.1 (d0),c
bset #3,c
move.1 c,(d0)
bset #15,st
inton
bclr #$a,st
jsr restore_regs
move.a (d0),a
add.a #5,d0
jmp (a)
work_mem
jsr avail_mem
move.a c,a
lsr.a #1,a ; / 2 fuer zwei speicher
move.a #min_mem,c
bgt.a a,c,.2
pop
bra.4 leave_code
.2
move.ao #work_mem_len,d0
move.a a,(d0)
move.a a,c
jsr blkalloc
exg.a d0,c
move.ao #work_mem_adr,d0
move.a c,(d0)
rtn
compress
move.ao #old_obj_adr,d0
move.a (d0),a
move.a #$70000,c
bge.a a,c,.1
rtnsc
.1
move.a a,r3 ;source adr
move.ao #last_norm,d0
move.a a,(d0)
move.ao #old_len,d0
move.a (d0),c
move.a c,r4
move.ao #work_mem_adr,d0 ; archiv-kennzeichen
move.a (d0),a ; anbringen
move.a a,d1
move.a #$02a2c,c
move.a c,(d1)
add.a #5,d1
exg.a d1,c
move.a c,d1
move.ao #strlen_adr,d0
move.a c,(d0)
add.a #5,d1
move.a #$24652,c ; !v
move.a c,(d1)
add.a #5,d1
move.ao #old_len,d0
move.a (d0),c
move.a c,(d1)
add.a #5,d1
exg.a d1,c
move.ao #work_mem_len,d0
move.a (d0),a
sub.a #10,a ; fuer $02a2c und laenge
sub.a #7,a ; 5 fuer zeichen, 2 fuer code
sub.a #5,a ; 5 fuer alte laenge
move.ao #mem_left,d0 ; mem_left setzen
move.a a,(d0)
move.ao #last_code_adr,d0
move.a c,(d0)
add.a #2,c
move.ao #dest_adr,d0
move.a c,(d0) ; dest adr
move.x #$800,c
move.x c,d ; dest counter und data
clr.s d
dec.s d ; muss auf anfang pruefen
;------------------------------------------------
nextnib
move.a r3,a
move.a a,d0
move.a (d0),c
move.a c,b ; fuer suchen des ersten nibs
move.a #256,c
sub.a c,a
beq.s d,0,.2 ; kein pruefen auf anfang noetig?
; doch
move.ao #old_obj_adr,d0
move.a (d0),c
blt.a a,c,.3 ;geht nicht...
inc.s d ;nicht mehr pruefen
bra .4
.3
move.a c,a
.4
.2
; in a.a ist jetzt die adresse, ab der verglichen werden soll
; in b.b ist das byte, das auch an der akt. source ist
move.a a,r2 ; adresse fuer vergleich
move.a r3,c
sub.a a,c ; zaehler fuer noch sinnvolle suche
move.a c,a ; in a
clr.b c
move.b c,r0 ; beste laenge, da drunter nix ist
dec.a a
bcc .5 ; wenn vergleich nix bringt, dann wech
bra hunt_fini
.5
move.a r2,c
move.a c,d0
.8
move.a (d0),c
beq.a c,b,.7 ; gleiches byte gefunden?
add.a #1,d0
.12 ;hier weiter suchen
dec.x a ; sollte reichen, sonst .a
bcc .8
bra hunt_fini
.7
exg.a d0,c
inc.a c
move.a c,d0
move.a c,r2 ; hier weiter vergleichen
; jetzt muss d0... mit source... verglichen werden
move.a r3,c ; source
move.a c,d1 ; nach d1
add.a #5,d1
add.a #4,d0
move.a #43,c
move.a c,b ; zaehler fuer max field-len
move.a r4,c ; nibs_left
bge.a c,b,.10m
move.a c,b
.10m
move.b #5,c ; neue beste? laenge
sub.b #6,b ; weil schon 1 lang und 0
bcs .9
.10
move.s (d1),c
move.s (d0),a
bne.s c,a,.9 ; ungleich, vergleich beenden
add.a #1,d0
add.a #1,d1
inc.b c
dec.b b ; max_field_len noch nicht ueber?
bcc .10
.10i
; wenn doch, suche abbrechen und bestes setzen...
move.b c,r0 ;beste laenge
move.a r2,c
dec.a c
move.a c,r1 ;adresse des besten
bra hunt_fini
.9
;vergleich ist beendet, in c.b ist gefundene laenge
; b wird jetzt nicht mehr gebraucht
move.b c,b
move.b r0,c
blt.b b,c,.11 ; ist neues feld groesser?
; ja, setzen!
move.b b,c
move.b c,r0 ;laenge und...
move.a r2,c
dec.a c
move.a c,r1 ; adresse des neuen besten setzen
.11
; jetzt weiter suchen...
move.a r3,c
move.a c,d0
move.a (d0),c ; such-byte von source
move.a c,b
move.a r2,c
move.a c,d0 ; suchadresse...
bra .12 ; weiter suchen
hunt_fini ; jetzt steht die beste folge fest:
; in r0.b ist ihre laenge, in r1.a ihre adresse.
; folgende register sind noch von bedeutung:
; r3=source_adr r4=nibs_left d=dest_data usw.
move.a r3,a
move.a r1,c
sub.a c,a
dec.a a ; dist= (source-adr)-1
move.a #255,c
ble.a a,c,.1b
bra no_field
.1b
move.a a,r1 ; jetzt ist distanz in r1.a
move.b r0,a
move.b #5,c
bge.b a,c,.1
bra no_field
.1
move.b #12,c
bge.b a,c,.8
;**** 5er - 11er Feld ****
bsr norm_out
move.b r0,a
sub.b #4,a
move.b #3-1,c
bsr bitsout
move.a r1,a
move.b #8-1,c
bsr bitsout
clr.a c
move.b r0,c
bra end_field
.8 ; ****** 12er - 43er Feld ******
bsr norm_out
bsr bit0out
bsr bit0out
bsr bit0out
move.b r0,a
sub.b #12,a
move.b #5-1,c
bsr bitsout
move.a r1,a
move.b #8-1,c
bsr bitsout
clr.a c
move.b r0,c
end_field ; in c.a zahl der nibbles im feld
move.a r4,a
sub.a c,a
bcc .1
bra.4 bad_arg_error
.1
move.a a,r4 ; neue nibs_left
move.a r3,a
add.a c,a
move.a a,r3 ; neue adresse
move.ao #last_norm,d0
move.a a,(d0)
move.a r4,a
beq.a a,0,compress_fini
bra nextnib
no_field
move.a r4,a
dec.a a
bcc .1
bra.4 bad_arg_error
.1
move.a a,r4 ; neue nibs_left
move.a r3,a
inc.a a
move.a a,r3 ; neue adresse
move.a r4,a
beq.a a,0,compress_fini
bra nextnib
compress_fini
bsr norm_out
test1
.2
clr.xs c
beq.xs c,d,.1
bsr bit0out
bra .2
.1
bsr bit0out
move.ao #dest_adr,d0
move.a (d0),a
sub.a #2,a ; letztes "code-byte" ist leer
move.ao #work_mem_adr,d0
move.a (d0),c
sub.a c,a ; in a.a new_len
bbc #0,a,.4
inc.a a
.4
move.ao #new_len,d0
move.a a,(d0)
move.ao #strlen_adr,d0
move.a (d0),c
move.a c,d0
move.a a,c
sub.a #5,c
move.a c,(d0)
move.ao #old_len,d0
move.a (d0),c
bge.a a,c,.3
rtncc
.3
rtnsc
norm_out
move.a r3,a
move.ao #last_norm,d0
move.a (d0),c
sub.a c,a ; in a.a zahl der norm-bytes
move.a a,r2 ; in r2.a auch
cont_norm
move.a r2,a
bne.a a,0,.1
; ******* 0 ********
bsr bit0out
rtn
.1
move.a #31,c
bgt.a a,c,.2
; **** 1 - 31 ****
bsr bit1out
move.a r2,a
move.b #5-1,c
bsr bitsout
move.a r2,c
bra copy_norm
.2
move.a #94,c
bgt.a a,c,.4
; *** 32 - 94 ****
bsr bit1out
bsr bit0out
bsr bit0out
bsr bit0out
bsr bit0out
bsr bit0out
move.a r2,a
sub.a #16,a ; -31
sub.a #15,a
move.b #6-1,c
bsr bitsout
move.a r2,c
bra copy_norm
.4 ; *** 95 und weiter ***
move.a #%100000000000,a
move.b #12-1,c
bsr bitsout
move.a r2,a
move.a #95,c
sub.a c,a
move.a a,r2
bsr copy_norm
bra cont_norm
bit1out
dec.xs d
bcs .1
add.b d,d
inc.b d
rtn
.1
move.ao #last_code_adr,d0
move.a (d0),c
move.a c,d1
move.b d,c
move.b c,(d1)
move.ao #dest_adr,d1
move.a (d1),c
move.a c,(d0)
add.a #2,c
move.a c,(d1)
move